package com.company.cloud.art.modules.app.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.sql.ast.expr.SQLCaseExpr;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.company.cloud.art.modules.api.response.Artist;
import com.company.cloud.art.modules.app.controller.req.*;
import com.company.cloud.art.modules.app.controller.resp.ExpoInfoDto;
import com.company.cloud.art.modules.base.entity.ExpoInfo;
import com.company.cloud.art.modules.base.entity.ExpoSignUpInfo;
import com.company.cloud.art.modules.base.service.ExpoInfoService;
import com.company.cloud.art.modules.base.service.ExpoJoinInfoService;
import com.company.cloud.art.modules.base.service.ExpoSignUpInfoService;
import com.company.cloud.art.modules.cache.models.*;
import com.company.cloud.art.modules.cache.utils.ArtConvertUtils;
import com.company.cloud.art.modules.mgr.mapper.ExpoJoinMapper;
import com.company.cloud.art.modules.mgr.service.ActArtistMgrService;
import com.company.cloud.common.asserts.ValidatorUtils;
import com.company.cloud.common.auth.annotation.Login;
import com.company.cloud.common.bean.BaseResult;
import com.company.cloud.common.bean.LoginSimpleUserInfo;
import com.company.cloud.common.constant.BaseConstant;
import com.company.cloud.common.constant.BaseReturnEnum;
import com.company.cloud.common.exception.BusinessException;
import com.company.cloud.common.utils.AuthContextUtils;
import com.company.cloud.common.utils.CheckUtils;
import com.company.cloud.common.utils.PinYinUtils;
import com.company.cloud.common.utils.StrSplitUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.function.Function;

@RestController
@RequestMapping("/app/art/expo")
@Api(tags = "ART_展会")
public class ExpoAppController {

    @Autowired
    private ExpoInfoService expoInfoService;

    @Autowired
    private ExpoJoinInfoService expoJoinInfoService;

    @Autowired
    private ExpoJoinMapper expoJoinMapper;

    @Autowired
    private ExpoSignUpInfoService expoSignUpInfoService;

    @Autowired
    private ActArtistMgrService actArtistMgrService;

    @PostMapping("/query")
    @ApiOperation(value = "展会查询", response = ExpoModel.class)
    public BaseResult query(@RequestBody ExpoQuery4PageParam params) {
        IPage<ExpoInfo> page = expoInfoService.page(new Page<>(params.getPage(), params.getRows()),
                new QueryWrapper<ExpoInfo>()
                        .eq("rows_state", BaseConstant.EnabledEnum.ENABLED.getCode())
                        .eq(StrUtil.isNotEmpty(params.getName()), "name", params.getName())
                        .eq(StrUtil.isNotEmpty(params.getBizVal1()), "biz_val1", params.getBizVal1())
                        .orderByDesc("orders")
        );
        IPage<ExpoModel> data = page.convert(new Function<ExpoInfo, ExpoModel>() {
            @Override
            public ExpoModel apply(ExpoInfo entity) {
                return ArtConvertUtils.getExpoModel(entity);
            }
        });
        return BaseResult.ok(data);
    }

    @GetMapping("/get")
    @ApiOperation(value = "展会详情", response = ExpoModel.class)
    public BaseResult get(@RequestParam("id") String id) {
        ExpoInfo entity = expoInfoService.getById(id);
        if (entity == null || BaseConstant.EnabledEnum.DISABLED.getCode().equals(entity.getRowsState())) {
            throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }
        ExpoModel data = ArtConvertUtils.getExpoModel(entity);
        ExpoInfoDto dto = new ExpoInfoDto();
        dto.setData(data);
        dto.setBanner(entity.getBanner());
        return BaseResult.ok(data);
    }

    @Login
    @PostMapping("/signUp")
    @ApiOperation(value = "展会报名", response = BaseResult.class)
    public BaseResult signUp(@RequestBody ExpoSignUpAddParam params) {
        LoginSimpleUserInfo userInfo = AuthContextUtils.getUser();
        ExpoSignUpInfo entity = expoSignUpInfoService.getOne(new QueryWrapper<ExpoSignUpInfo>()
                .eq("expo_no", params.getExpoNo())
                .eq("user_id", userInfo.getId())

        );
        if (entity != null) {
            throw new BusinessException(BaseReturnEnum.PARAM_NULL.getCode(), "已报名");
        }
        entity = new ExpoSignUpInfo();
        entity.setExpoNo(params.getExpoNo());
        entity.setBoothNo(params.getBoothNo());
        entity.setUserId(userInfo.getId());
        entity.setBizVal(params.getBizVal());
        entity.setState(BaseConstant.YNEnum.YES.getCode());
        entity.addCreateParam(userInfo);
        entity.addEditParam(userInfo);
        expoSignUpInfoService.save(entity);
        return BaseResult.ok();
    }

    @Login
    @PostMapping("/mySignUpList")
    @ApiOperation(value = "查询我的展会报名", response = ExpoSignUpModel.class)
    public BaseResult mySignUpList(@RequestBody ExpoMySignUpListParam params) {
        LoginSimpleUserInfo userInfo = AuthContextUtils.getUser();
        List<ExpoSignUpInfo> list = expoSignUpInfoService.list(new QueryWrapper<ExpoSignUpInfo>()
                .eq(StrUtil.isNotEmpty(params.getExpoNo()), "expo_no", params.getExpoNo())
                .eq("user_id", userInfo.getId())
                .orderByDesc("cdt")
        );
        if (CollUtil.isEmpty(list)) {
            return BaseResult.ok();
        }

        List<ExpoSignUpModel> data = new ArrayList<>();
        Set<String> expoNos = new HashSet<>();
        list.forEach(item -> {
            expoNos.add(item.getExpoNo());
        });

        List<ExpoInfo> expoList = expoInfoService.listByIds(expoNos);
        list.forEach(item -> {
            data.add(ArtConvertUtils.getExpoSignUpModel(item, expoList));
        });
        return BaseResult.ok(data);
    }


    @PostMapping("/queryJoin")
    @ApiOperation(value = "参展公司查询", response = ExpoJoinCompanyModel.class)
    public BaseResult queryJoin(@RequestBody ExpoJoinQuery4PageParam params) {
        ValidatorUtils.validate(params);
        IPage<ExpoJoinCompanyModel> page = null;
        if (StrUtil.isEmpty(params.getExpoNo()) && StrUtil.isEmpty(params.getBoothNo())) {
            page = expoJoinMapper.queryExpoJoinCompany2(
                    new Page<ExpoJoinCompanyModel>(params.getPage(), params.getRows()),
                    new QueryWrapper<ExpoJoinCompanyModel>()
                            .eq(StrUtil.isNotEmpty(params.getOrgNo()), "b.company_no", params.getOrgNo())
                            .eq(StrUtil.isNotEmpty(params.getOrgName()), "b.name", params.getOrgName())
                            .eq("b.rows_state", BaseConstant.EnabledEnum.ENABLED.getCode())
                            .orderByDesc("b.name")
            );
        } else {
            page = expoJoinMapper.queryExpoJoinCompany(
                    new Page<ExpoJoinCompanyModel>(params.getPage(), params.getRows()),
                    new QueryWrapper<ExpoJoinCompanyModel>()
                            .eq(StrUtil.isNotEmpty(params.getExpoNo()), "a.expo_no", params.getExpoNo())
                            .eq(StrUtil.isNotEmpty(params.getBoothNo()), "a.booth_no", params.getBoothNo())
                            .eq(StrUtil.isNotEmpty(params.getOrgNo()), "b.company_no", params.getOrgNo())
                            .eq(StrUtil.isNotEmpty(params.getOrgName()), "b.name", params.getOrgName())
                            .eq("a.state", BaseConstant.YNEnum.YES.getCode())
                            .eq("b.rows_state", BaseConstant.EnabledEnum.ENABLED.getCode())
                            .orderByDesc("a.orders")
            );
        }

        if (page != null && CollUtil.isNotEmpty(page.getRecords())) {
            page.getRecords().forEach(item -> {
                item.setNameFirstPy(PinYinUtils.toFirstChar(item.getName()));
            });
        }
        return BaseResult.ok(page);
    }


    @PostMapping("/queryJoinList")
    @ApiOperation(value = "参展公司查询(不分页)", response = ExpoJoinCompanyGroupModel.class)
    public BaseResult queryJoinList(@RequestBody ExpoJoinQuery4PageParam params) {
        ValidatorUtils.validate(params);
        params.setRows(1000);
        params.setPage(1);
        IPage<ExpoJoinCompanyModel> page = expoJoinMapper.queryExpoJoinCompany(
                new Page<ExpoJoinCompanyModel>(params.getPage(), params.getRows()),
                new QueryWrapper<ExpoJoinCompanyModel>()
                        .eq(StrUtil.isNotEmpty(params.getExpoNo()), "a.expo_no", params.getExpoNo())
                        .eq(StrUtil.isNotEmpty(params.getOrgNo()), "a.org_no", params.getOrgNo())
                        .eq(StrUtil.isNotEmpty(params.getBoothNo()), "a.booth_no", params.getBoothNo())
                        .eq("a.state", BaseConstant.YNEnum.YES.getCode())
                        .eq("b.rows_state", BaseConstant.EnabledEnum.ENABLED.getCode())
        );

        Map<String, List<ExpoJoinCompanyModel>> joinMap = new HashMap<String, List<ExpoJoinCompanyModel>>();
        if (page != null && CollUtil.isNotEmpty(page.getRecords())) {
            page.getRecords().forEach(item -> {
                item.setNameFirstPy(PinYinUtils.toFirstChar(item.getName()));
                if (StrUtil.isEmpty(params.getNameFirstPy()) || item.getNameFirstPy().equals(params.getNameFirstPy())) {
                    List<ExpoJoinCompanyModel> list = joinMap.get(item.getNameFirstPy());
                    if (list == null) {
                        list = new ArrayList<>();
                        joinMap.put(item.getNameFirstPy(), list);
                    }
                    list.add(item);
                }
            });
        }

        List<ExpoJoinCompanyGroupModel> data = new ArrayList<>();
        joinMap.forEach((k, v) -> {
            data.add(new ExpoJoinCompanyGroupModel(k, v));
        });
        return BaseResult.ok(data);
    }


    @PostMapping("/queryJoinPrdList")
    @ApiOperation(value = "查询参展公司的产品(不分页)", response = ExpoJoinProductModel.class)
    public BaseResult queryJoinPrdList(@RequestBody ExpoJoinPrdQuery4PageParam params) {
        IPage<ExpoJoinProductModel> page = expoJoinMapper.queryExpoJoinProduct(
                new Page<ExpoJoinProductModel>(1, 1000),
                new QueryWrapper<ExpoJoinProductModel>()
                        .eq(StrUtil.isNotEmpty(params.getExpoNo()), "b.expo_no", params.getExpoNo())
                        .eq(StrUtil.isNotEmpty(params.getOrgNo()), "b.org_no", params.getOrgNo())
                        .orderByDesc("b.orders")
        );
        if (page == null) {
            return BaseResult.ok();
        }

        Set<String> artistNos = new HashSet<String>();
        page.getRecords().forEach(item -> {
            if (StrUtil.isNotEmpty(item.getPrdBizValue4())) {
                Set<String> artistNos2 = StrSplitUtils.parse2set(item.getPrdBizValue4(), String.class);
                artistNos.addAll(artistNos2);
            }
        });

        Map<String, Artist> artistMap = actArtistMgrService.artistInfoMap(artistNos);

        List<ExpoJoinProductModel> data = new ArrayList<>();
        page.getRecords().forEach(item -> {
            if (StrUtil.isNotEmpty(item.getPrdBizValue4())) {
                Set<String> artistNos3 = StrSplitUtils.parse2set(item.getPrdBizValue4(), String.class);
                if (artistNos3.size() > 0) {
                    for (String ano : artistNos3) {
                        Artist artist = artistMap.get(ano);
                        if (artist != null) {
                            item.addArtist(this.getArtist(artist));
                        }
                    }
                }
            }
            data.add(item);
        });
        return BaseResult.ok(data);
    }

    private Map<String, Object> getArtist(Artist entity) {
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("artistNo", entity.getArtistNo());
        data.put("name", entity.getName());
        data.put("nameFirstPy", entity.getNameFirstPy());
        data.put("headImg", entity.getHeadImg());
        data.put("prdNum", entity.getPrdNum());
        return data;
    }

}
